package com.lychee.moli.utils;

import com.lychee.moli.entity.IdentityEntity;
import io.jsonwebtoken.*;
import org.apache.log4j.Logger;

import javax.crypto.spec.SecretKeySpec;
import javax.xml.bind.DatatypeConverter;
import java.security.Key;
import java.util.Date;

/**
 * Created by Lychee on 2018/4/11 08:58.
 * <p>
 * Author:Hejingzhou
 * <p>
 * Email:tcowork@163.com
 * <p>
 * from：https://stormpath.com/blog/jwt-java-create-verify
 */
public class TokenUtils {

    public static String SECRET_KEY = "APPSECRET";
    private static Logger logger = Logger.getLogger(TokenUtils.class);

    /**
     * 创建Token
     *
     * @param identityEntity
     * @param apiKeySecret
     * @return
     */
    public static String createToken(IdentityEntity identityEntity, String apiKeySecret) {

        SignatureAlgorithm signatureAlgorithm = SignatureAlgorithm.HS256;

        //获得当前的时间戳
        long nowMill = System.currentTimeMillis();
        Date now = new Date(nowMill);

        byte[] apiKeySectetBytes = DatatypeConverter.parseBase64Binary(apiKeySecret);
        Key signingKey = new SecretKeySpec(apiKeySectetBytes, signatureAlgorithm.getJcaName());

        //设置Payload  荷载  就是具体的数据
        JwtBuilder jwtBuilder = Jwts.builder()
                .setId(identityEntity.getUserId())
                .setIssuedAt(now)
                .setSubject(identityEntity.getUserId() + "," + identityEntity.getUserName())
                .setIssuer(identityEntity.getIssuer())
                .signWith(signatureAlgorithm, signingKey);

        long ttlMillis = identityEntity.getDuration();

        if (ttlMillis >= 0) {
            long expMillis = nowMill + ttlMillis;
            Date exp = new Date(expMillis);
            jwtBuilder.setExpiration(exp);
        }
        logger.info("生成token 成功");
        return jwtBuilder.compact();
    }


    /**
     * 解析Token数据信息
     *
     * @param token
     * @param apiKeySecret
     * @return
     */
    public static IdentityEntity parseTokenMessage(String token, String apiKeySecret) throws
            ExpiredJwtException,
            UnsupportedJwtException,
            MalformedJwtException,
            SignatureException,
            IllegalArgumentException {
        IdentityEntity identityEntity = null;
        try {

            Claims claims = Jwts.parser()
                    .setSigningKey(DatatypeConverter.parseBase64Binary(apiKeySecret))
                    .parseClaimsJws(token)
                    .getBody();
            String[] subjectInfos = claims.getSubject().split(",");
            String userId = subjectInfos[0];
            String userName = subjectInfos[1];
            identityEntity = new IdentityEntity();
            identityEntity.setUserId(userId);
            identityEntity.setUserName(userName);
            identityEntity.setDuration(claims.getExpiration().getTime());
            logger.info("已登录的用户 有效Token");
        } catch (ExpiredJwtException e) {
            logger.trace("Token 过期了");
            e.printStackTrace();
        } catch (UnsupportedJwtException e) {
            logger.trace("不支持 这个JWT");
            e.printStackTrace();
        } catch (MalformedJwtException e) {
            logger.trace("JWT 格式错误");
            e.printStackTrace();
        } catch (SignatureException e) {
            logger.trace("签名异常");
            e.printStackTrace();
        } catch (IllegalArgumentException e) {
            logger.trace("参数异常");
            e.printStackTrace();
        }
        return identityEntity;
    }
}
